﻿using System;
using System.Collections.Concurrent;
using System.Data;
using System.Reflection;

namespace Sgr.Domain.Uow
{
    /// <summary>
    /// UnitOfWork特性的帮助类，用于高效获取和缓存UnitOfWorkAttribute信息
    /// </summary>
    public static class UnitOfWorkHelper
    {
        // 使用ConcurrentDictionary作为线程安全的缓存容器
        private static readonly ConcurrentDictionary<Type, UnitOfWorkAttribute?> AttributeCache
            = new ConcurrentDictionary<Type, UnitOfWorkAttribute?>();

        /// <summary>
        /// 获取指定类型上的UnitOfWorkAttribute信息
        /// </summary>
        /// <param name="type">要检查的类型</param>
        /// <returns>UnitOfWorkAttribute实例，如果未找到则返回null</returns>
        public static UnitOfWorkAttribute? GetUnitOfWorkAttribute(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            return AttributeCache.GetOrAdd(type, t =>
            {
                // 获取类型上的UnitOfWorkAttribute，包括继承的特性
                return t.GetCustomAttribute<UnitOfWorkAttribute>(true);
            });
        }

        /// <summary>
        /// 检查指定类型是否标记了UnitOfWorkAttribute
        /// </summary>
        /// <param name="type">要检查的类型</param>
        /// <returns>如果类型标记了UnitOfWorkAttribute则返回true，否则返回false</returns>
        public static bool HasUnitOfWorkAttribute(Type type)
        {
            return GetUnitOfWorkAttribute(type) != null;
        }

        /// <summary>
        /// 获取类型的UnitOfWork选项
        /// </summary>
        /// <param name="type">要检查的类型</param>
        /// <returns>UnitOfWorkOption实例</returns>
        public static UnitOfWorkOption GetUnitOfWorkOptions(Type type)
        {
            var options = new UnitOfWorkOption();

            var attribute = GetUnitOfWorkAttribute(type);

            if (attribute != null)
            {
                attribute.SetOptions(options);
            }

            return options;
        }

        /// <summary>
        /// 清除特性缓存
        /// </summary>
        public static void ClearCache()
        {
            AttributeCache.Clear();
        }

        /// <summary>
        /// 获取特性缓存的数量
        /// </summary>
        public static int CacheCount => AttributeCache.Count;
    }
}